<?php

namespace App\Http\Controllers;

use App\Http\Tools\aliyun;
use App\Models\User;
use EasyWeChat\Factory;
use EasyWeChatComposer\EasyWeChat;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use Tymon\JWTAuth\JWTAuth;

class AuthController extends Controller
{

    public function __construct()
    {
        $this->middleware('auth:api', ['except' =>
            [
                'login',
                'register',
                'registerStep2',
                'weAppLogin',
                'logout',
                'me'
            ]
        ]);
    }

    public function login()
    {
        $validator = validator(\request()->all(), [
            'phone' => 'required|numeric',
            'password' => 'required|string'
        ]);
        if ($validator->fails()) {
            return api_error('002');
        }
        $phone = \request('phone');
        $password = \request('password');

        $user = User::where('phone', $phone)
            ->where('password', hash('sha256', $password))
            ->with('role')
            ->first();

        if (is_null($user)) {
            return api_error('004');
        }

        $token = auth()->login($user);

        return $this->respondWithToken($token);
    }

    public function register()
    {
        $validator = validator(\request()->all(), [
            'name' => 'required|string',
            'phone' => 'required|numeric',
            'password' => 'required|string'
        ]);
        if ($validator->fails()) {
            return api_error('002');
        }

        $name = \request('name');
        $phone = \request('phone');
        $password = \request('password');
        if (User::where('phone', $phone)->count() !== 0) {
            return api_error('003');
        }

        $aliyun = new Aliyun();
        $code = $aliyun->createCode();
        $aliyun->sendCode($phone, $code);
        $session_id = Str::random(32);
        Cache::put(
            'register_'.$session_id,
            [
                'name' => $name,
                'phone' => $phone,
                'password' => $password,
                'created_at' => time(),
                'code' => $code,
            ],
            1000
        );
        return api_output([
            'session_id' => $session_id
        ]);
    }

    public function registerStep2()
    {
        $validator = validator(\request()->all(), [
            'session_id' => 'required|string',
            'code' => 'required|string'
        ]);
        if ($validator->fails()) {
            return api_error('002');
        }

        $session = Cache::get('register_'.\request('session_id'));
        if ($session['code'] != \request('code')) {
            return api_error('009');
        }

        $user = new User();
        $user->name = $session['name'];
        $user->phone = $session['phone'];
        $user->password = hash('sha256', $session['password']);
        $user->invitation_code = Str::random(32);
        $user->save();
        $token = auth()->login($user);

        return $this->respondWithToken($token);
    }

    public function me()
    {
        try {
            $user = auth()->user();
        } catch (Exception $e) {
            $user = false;
        }
        
        if(!$user){
            auth()->logout();
            return api_output(['message' => 'Successfully logged out']);
        }
        else{
            return api_output([
                'name' => $user->name,
                'phone' => $user->phone,
                'role' => $user->role->name,
                'invitation_code' => $user->role_id == 1 ? '' : $user->invitation_code,
                'avatar' => $user->avatar
            ]);
            return response()->json(auth()->user());
        }
    }

    public function logout()
    {
        try {
            // auth()->logout();
            return api_output(['message' => 'Successfully logged out']);
        } catch (Exception $e) {
            return api_output(['message' => 'Successfully logged out']);
        }
    }

    public function refresh()
    {
        return $this->respondWithToken(auth()->refresh());
    }

    protected function respondWithToken($token)
    {
        return api_output([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth()->factory()->getTTL() * 60
        ]);
    }

    public function resetPassword()
    {
        $validator = validator(\request()->all(), [
            'old_password' => 'required|string',
            'new_password' => 'required|string'
        ]);
        if ($validator->fails()) {
            return api_error('002');
        }

        $user = auth()->user();
        $oldPwd = \request('old_password');
        $newPwd = \request('new_password');

        if ($user->password !== hash('sha256', $oldPwd)) {
            return api_error('005');
        }

        $user->password = hash('sha256', $newPwd);
        $user->save();
        auth()->logout();
        return api_output(true);
    }

    public function bindAgent(){
        $validator = validator(\request()->all(), [
            'code' => 'required|string',
        ]);
        if ($validator->fails()) {
            return api_error('002');
        }

        $code = \request('code');
        $user = auth()->user();

        if(!is_null($user->agent)){
            return api_error('010');
        }

        $agent = User::where('invitation_code', $code)->first();
        if(is_null($agent)){
            return api_error('011');
        }

        $user->agent()->associate($agent);
        $user->save();

        return api_output(true);
    }

}


